package io.gitee.zhangbinhub.admin.oauth.controller.api

import cn.dev33.satoken.annotation.SaCheckPermission
import io.gitee.zhangbinhub.acp.boot.exceptions.WebException
import io.gitee.zhangbinhub.acp.boot.log.LogAdapter
import io.gitee.zhangbinhub.acp.core.common.CommonTools
import io.gitee.zhangbinhub.admin.common.api.OauthApi
import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode
import io.gitee.zhangbinhub.admin.common.constant.RoleCode
import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo
import io.gitee.zhangbinhub.admin.common.vo.InfoVo
import io.gitee.zhangbinhub.admin.oauth.bus.publish.ReloadDataEventPublish
import io.gitee.zhangbinhub.admin.oauth.entity.Application
import io.gitee.zhangbinhub.admin.oauth.po.ApplicationPo
import io.gitee.zhangbinhub.admin.oauth.po.ApplicationQueryPo
import io.gitee.zhangbinhub.admin.oauth.service.ApplicationService
import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import io.swagger.annotations.ApiParam
import org.noear.solon.annotation.*
import org.noear.solon.core.handle.MethodType
import org.noear.solon.core.util.MimeType
import org.noear.solon.validation.annotation.*

@Valid
@Controller
@Api("应用信息")
open class ApplicationController(
    @Inject logAdapter: LogAdapter,
    private val applicationService: ApplicationService,
    private val reloadDataEventPublish: ReloadDataEventPublish
) : BaseResourceServerController(logAdapter) {

    @ApiOperation("新建应用信息", notes = "应用名称、token 有效期、refresh token 有效期")
    @SaCheckPermission(ModuleFuncCode.appAdd, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PUT],
        value = OauthApi.basePath + OauthApi.appConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    fun add(@Body @Validated applicationPo: ApplicationPo): Application =
        applicationService.doCreate(applicationPo).also {
            reloadDataEventPublish.doNotifyRefreshApplication()
        }

    @ApiOperation("删除指定的信息")
    @SaCheckPermission(ModuleFuncCode.appDelete, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.DELETE],
        value = OauthApi.basePath + OauthApi.appConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    fun delete(
        @ApiParam(name = "id列表", required = true)
        @NotEmpty(message = "id不能为空")
        @NotNull(message = "id不能为空")
        @Body
        idList: MutableList<String>
    ): InfoVo {
        applicationService.doDelete(idList)
        reloadDataEventPublish.doNotifyRefreshApplication()
        return InfoVo(message = "删除成功")
    }

    @ApiOperation("更新指定的信息", notes = "可更新应用名称、token 有效期、refresh token 有效期")
    @SaCheckPermission(ModuleFuncCode.appUpdate, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.PATCH],
        value = OauthApi.basePath + OauthApi.appConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun update(@Body @Validated applicationPo: ApplicationPo): Application {
        if (CommonTools.isNullStr(applicationPo.id)) {
            throw WebException("ID不能为空")
        }
        return applicationService.doUpdate(applicationPo).also {
            reloadDataEventPublish.doNotifyRefreshApplication()
        }
    }

    @ApiOperation("查询信息列表", notes = "查询条件：应用名称")
    @SaCheckPermission(ModuleFuncCode.appQuery, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.POST],
        value = OauthApi.basePath + OauthApi.appConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun query(@Body @Validated applicationQueryPo: ApplicationQueryPo): CustomerQueryPageVo<Application> =
        applicationService.doQuery(applicationQueryPo)

    @ApiOperation("获取应用列表", notes = "查询所有应用列表")
    @SaCheckPermission(ModuleFuncCode.sysConfig, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.appConfig,
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    fun appList(): List<Application> = applicationService.getAppList()

    @ApiOperation("更新应用密钥")
    @SaCheckPermission(ModuleFuncCode.appUpdateSecret, orRole = [RoleCode.SUPER])
    @Mapping(
        method = [MethodType.GET],
        value = OauthApi.basePath + OauthApi.updateSecret + "/{appId}",
        produces = MimeType.APPLICATION_JSON_VALUE
    )
    @Throws(WebException::class)
    fun updateSecret(
        @ApiParam(name = "应用id", required = true)
        @NotBlank(message = "应用id不能为空")
        @Path(name = "appId")
        appId: String
    ): Application = applicationService.doUpdateSecret(appId).also {
        reloadDataEventPublish.doNotifyRefreshApplication()
    }
}
